<?php

namespace App\Services;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use common\utils\RedisKeys;
use common\utils\SysCode;
use common\enum\SettingEnum;
use App\Models\Setting;
use App\Models\SettingLog;

class SettingService
{

    public static function getRegisterItems()
    {
        return array_filter(self::getArray(SettingEnum::USER_REGISTER_ITEMS), function ($v) {
            return $v['show'];
        });
    }

    public static function setRegisterItems($items)
    {
        return self::setArray(SettingEnum::USER_REGISTER_ITEMS, $items);
    }

    public static function getUserRegisterSwitch()
    {
        return self::getBool(SettingEnum::USER_REGISTER_SWITCH);
    }

    public static function setUserRegisterSwitch($switch)
    {
        return self::setBool(SettingEnum::USER_REGISTER_SWITCH, $switch);
    }

    public static function getVCodeSwitch()
    {
        return self::getBool(SettingEnum::VCODE_SWITCH);
    }

    public static function setVCodeSwitch($switch)
    {
        return self::setBool(SettingEnum::VCODE_SWITCH, $switch);
    }

    public static function getAgentDefaultSite()
    {
        return self::get(SettingEnum::AGENT_DEFAULT_SITE);
    }

    public static function setAgentDefaultSite($site)
    {
        return self::set(SettingEnum::AGENT_DEFAULT_SITE, $site);
    }

    public static function getLoginPasswordWrongTimes()
    {
        return self::get(SettingEnum::LOGIN_PASSWORD_WRONG_TIMES);
    }

    public static function setLoginPasswordWrongTimes($times)
    {
        return self::set(SettingEnum::LOGIN_PASSWORD_WRONG_TIMES, times);
    }

    public static function getWithdrawPasswordWrongTimes()
    {
        return self::get(SettingEnum::WITHDRAW_PASSWORD_WRONG_TIMES);
    }

    public static function setWithdrawPasswordWrongTimes($times)
    {
        return self::set(SettingEnum::WITHDRAW_PASSWORD_WRONG_TIMES, $times);
    }

    public static function getValidMemberCondition()
    {
        return self::getArray(SettingEnum::VALID_MEMBER_CONDITION);
    }

    public static function setValidMemberCondition($condition)
    {
        return self::setArray(SettingEnum::VALID_MEMBER_CONDITION, $condition);
    }

    public static function getDemoSwitch()
    {
        return self::getBool(SettingEnum::DEMO_SWITCH);
    }

    public static function setDemoSwitch($switch)
    {
        return self::setBool(SettingEnum::DEMO_SWITCH, $switch);
    }

    public static function getAuditPercentage()
    {
        return self::getArray(SettingEnum::AUDIT_PERCENTAGE);
    }

    public static function setAuditPercentage($audit)
    {
        return self::setArray(SettingEnum::AUDIT_PERCENTAGE, $audit);
    }

    public static function getCustomerServiceSetting()
    {
        return self::getArray(SettingEnum::CUSTOMER_SERVICE_SETTING);
    }

    public static function setCustomerServiceSetting($setting)
    {
        return self::setArray(SettingEnum::CUSTOMER_SERVICE_SETTING, $setting);
    }

    public static function getArray($key)
    {
        $arr = self::get($key);
        if (!$arr) {
            return [];
        }
        return json_decode($arr, true);
    }

    public static function setArray($key, $value)
    {
        return self::set($key, json_encode($value));
    }

    public static function getBool($key)
    {
        return self::get($key) == 1;
    }

    public static function setBool($key, $value)
    {
        return self::set($key, $value ? 1 : 0);
    }

    public static function get($key, $cache = true)
    {
        $redis = Redis::connection();
        if ($cache) {
            $value = $redis->get(RedisKeys::SETTING_KEY . $key);
            if ($value != null) {
                return $value;
            }
        }
        $setting = Setting::where(['key' => $key])->first();
        if ($setting) {
            $redis->set(RedisKeys::SETTING_KEY . $key, $setting->value);
            return $setting->value;
        }
        return null;
    }

    public static function set($key, $value)
    {
        DB::beginTransaction();
        try {
            $old = self::get($key, false);
            if ($old === null) {
                $old = '';
                $setting = new Setting();
                $setting->key = $key;
                $setting->value = $value;
                $setting->save();
            } else {
                Setting::where(['key' => $key])->update(['value' => 1]);
            }

            $log = new SettingLog();
            $log->key = $key;
            $log->new = $value;
            $log->old = $old;
            $user = Auth::user();
            if ($user) {
                $log->updater_id = $user->id;
                $log->updater_name = $user->username;
            }
            $log->save();
            DB::commit();

            $redis = Redis::connection();
            $redis->set(RedisKeys::SETTING_KEY . $key, $value);
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Setting Error: " . $e->getMessage(), ['key' => $key, 'value' => $value]);
            return false;
        }
    }
}
